package com.ts.api.module.match.plan.internal.executor.handler;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Empty;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeResult;
import com.ts.api.module.match.plan.internal.executor.model.PlanExecuteTask;
import com.ts.api.module.match.plan.internal.qualification.model.PlanQualificationResult;
import com.ts.api.module.match.plan.model.AbstractPlanMatch;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 *  计划匹配任务执行器
 *
 *  @author Pan
 */
@Component
@Slf4j
public class PlanExecutorHandler {

    @Autowired
    private PlanExecutorTaskHandler planExecutorTaskHandler;

    /**
     *  同步执行-执行计划匹配任务，返回已完成执行结果
     *
     *  @param  planQualificationResult   执行器参数业务实体类
     *  @return List
     */
    public List<PlanDistributeResult> executeSync(PlanQualificationResult planQualificationResult) {
        //  无资质通过计划则直接返回
        List<ProductPlanPO> listPlanQualification = planQualificationResult.getListPlanQualification();
        if (ValidParam.isEmpty(listPlanQualification)) {
            return Empty.list();
        }

        List<PlanDistributeResult> listResult = CollUtils.newArrayList(listPlanQualification.size());

        //  获取任务上下文-创建任务
        for (ProductPlanPO productPlanPO : listPlanQualification) {
            PlanExecuteTask planExecuteTask = PlanExecuteTask.of(planQualificationResult, productPlanPO);
            PlanDistributeResult submit = planExecutorTaskHandler.submitSync(planExecuteTask);
            listResult.add(submit);
        }
        //  返回执行成功结果
        return CollUtils.find(listResult, PlanDistributeResult::getDistributeStatus);
    }

    /**
     *  执行计划匹配任务，返回已完成执行结果
     *
     *  @param  planQualificationResult   执行器参数业务实体类
     *  @return List
     */
    public List<PlanDistributeResult> execute(PlanQualificationResult planQualificationResult) {
        //  无资质通过计划则直接返回
        List<ProductPlanPO> listPlanQualification = planQualificationResult.getListPlanQualification();
        if (ValidParam.isEmpty(listPlanQualification)) {
            return Empty.list();
        }

        listPlanQualification.sort(Comparator.comparing(ProductPlanPO::getPlanType));

        try (ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor()) {
            List<Callable<PlanDistributeResult>> callables = CollUtils.newArrayList(listPlanQualification.size());
            //  获取任务上下文-创建任务
            for (ProductPlanPO productPlanPO : listPlanQualification) {
                PlanExecuteTask planExecuteTask = PlanExecuteTask.of(planQualificationResult, productPlanPO);
                callables.add(planExecutorTaskHandler.submit(planExecuteTask));
            }

            //  限制超时参数
            AbstractPlanMatch abstractPlanMatch = planQualificationResult.getAbstractPlanMatch();
            Integer httpTimeout = abstractPlanMatch.getHttpTimeout();

            //  执行
            List<PlanDistributeResult> listResult = pool.invokeAll(callables, httpTimeout - 200, TimeUnit.MILLISECONDS)
                .stream()
                .filter(future -> future.state() == Future.State.SUCCESS && ValidParam.isNotNull(future))
                .map(Future::resultNow)
            .toList();

            //  返回执行成功结果
            return CollUtils.find(listResult, PlanDistributeResult::getDistributeStatus);
        } catch (Exception e) {
            //  do noting
        }
        return Empty.list();
    }
}
